/**
 * WebSocket 连接管理器
 * 用于实时接收服务器推送的通知
 */

import { config } from '@/config'

class WebSocketManager {
  constructor() {
    this.ws = null
    this.url = null
    this.clientId = null
    this.reconnectAttempts = 0
    this.maxReconnectAttempts = 5
    this.reconnectDelay = 3000 // 重连延迟（毫秒）
    this.messageListeners = [] // 消息监听器列表
    this.isManualClose = false // 是否手动关闭
    this.heartbeatTimer = null
  }

  /**
   * 初始化 WebSocket 连接
   * @param {number} userId - 用户ID
   * @param {string} baseUrl - WebSocket 服务器地址，默认为配置文件中的地址
   */
  init(userId, baseUrl = null) {
    const newClientId = String(userId)
    
    // 如果已经连接了相同的用户，不需要重新初始化
    if (this.clientId === newClientId && this.isConnected()) {
      console.log(`[WebSocket] ✅ 已连接，无需重新初始化`)
      return
    }
    
    // 如果正在连接不同的用户，先断开旧连接
    if (this.clientId && this.clientId !== newClientId) {
      console.log(`[WebSocket] 🔄 切换用户: ${this.clientId} → ${newClientId}`)
      this.disconnect()
    }
    
    this.clientId = newClientId
    
    if (!baseUrl) {
      baseUrl = config.WS_BASE_URL
    }
    
    this.url = `${baseUrl}/indiv/ws/${this.clientId}`
    console.log(`[WebSocket] 🔌 连接到客户端: ${this.clientId}`)
    
    this.connect()
  }

  /**
   * 建立 WebSocket 连接
   */
  connect() {
    try {
      this.ws = new WebSocket(this.url)
      this.isManualClose = false
      
      this.ws.onopen = () => {
        console.log(`[WebSocket] ✅ 连接已建立，客户端: ${this.clientId}`)
        this.reconnectAttempts = 0 // 重置重连次数
        this.startHeartbeat()
        // 触发连接成功事件
        this.notifyListeners({
          type: 'connected',
          message: 'WebSocket 连接已建立',
          clientId: this.clientId
        })
      }
      
      this.ws.onmessage = (event) => {
        console.log('[WebSocket] 📨 收到消息:', event.data)
        try {
          const data = JSON.parse(event.data)
          this.notifyListeners(data)
        } catch (e) {
          console.warn('[WebSocket] ⚠️ 消息解析失败:', e)
          this.notifyListeners({
            type: 'message',
            data: event.data
          })
        }
      }
      
      this.ws.onerror = (error) => {
        console.error('[WebSocket] 连接错误:', error)
        this.notifyListeners({
          type: 'error',
          message: 'WebSocket 连接出错'
        })
      }
      
      this.ws.onclose = () => {
        this.stopHeartbeat()
        
        if (!this.isManualClose && this.reconnectAttempts < this.maxReconnectAttempts) {
          this.reconnectAttempts++
          console.log(`[WebSocket] 重连中 (${this.reconnectAttempts}/${this.maxReconnectAttempts})...`)
          setTimeout(() => this.connect(), this.reconnectDelay)
        } else if (this.isManualClose) {
          this.notifyListeners({
            type: 'disconnected',
            message: 'WebSocket 连接已断开'
          })
        } else {
          console.warn('[WebSocket] 重连失败')
          this.notifyListeners({
            type: 'reconnect_failed',
            message: '无法重新连接到服务器'
          })
        }
      }
    } catch (error) {
      console.error('[WebSocket] 连接失败:', error)
      this.notifyListeners({
        type: 'error',
        message: '无法连接到 WebSocket 服务器'
      })
    }
  }

  /**
   * 启动心跳检测
   */
  startHeartbeat() {
    this.stopHeartbeat()
    // 每30秒发送一次心跳
    this.heartbeatTimer = setInterval(() => {
      if (this.ws && this.ws.readyState === WebSocket.OPEN) {
        try {
          this.ws.send(JSON.stringify({
            type: 'heartbeat',
            timestamp: Date.now()
          }))
        } catch (error) {
          console.warn('[WebSocket] 心跳发送失败:', error)
        }
      }
    }, 30000)
  }

  /**
   * 停止心跳检测
   */
  stopHeartbeat() {
    if (this.heartbeatTimer) {
      clearInterval(this.heartbeatTimer)
      this.heartbeatTimer = null
    }
  }

  /**
   * 添加消息监听器
   * @param {Function} callback - 回调函数，接收消息数据
   * @returns {Function} 返回取消监听函数
   */
  onMessage(callback) {
    this.messageListeners.push(callback)
    
    // 返回取消监听函数
    return () => {
      const index = this.messageListeners.indexOf(callback)
      if (index > -1) {
        this.messageListeners.splice(index, 1)
      }
    }
  }

  /**
   * 通知所有监听器
   * @param {Object} data - 消息数据
   */
  notifyListeners(data) {
    this.messageListeners.forEach((callback) => {
      try {
        callback(data)
      } catch (error) {
        console.error('[WebSocket] ❌ 监听器执行出错:', error)
      }
    })
  }

  /**
   * 发送消息
   * @param {Object} data - 消息数据
   */
  send(data) {
    if (this.ws && this.ws.readyState === WebSocket.OPEN) {
      try {
        this.ws.send(JSON.stringify(data))
      } catch (error) {
        console.error('[WebSocket] 发送失败:', error)
      }
    } else {
      console.warn('[WebSocket] 连接未就绪')
    }
  }

  /**
   * 断开连接
   */
  disconnect() {
    this.isManualClose = true
    this.stopHeartbeat()
    if (this.ws) {
      this.ws.close()
      this.ws = null
    }
  }

  /**
   * 获取连接状态
   */
  isConnected() {
    return this.ws && this.ws.readyState === WebSocket.OPEN
  }

  /**
   * 重新连接
   */
  reconnect() {
    this.disconnect()
    this.reconnectAttempts = 0
    setTimeout(() => this.connect(), 1000)
  }

  /**
   * 获取调试信息
   */
  getDebugInfo() {
    const info = {
      clientId: this.clientId,
      url: this.url,
      isConnected: this.isConnected(),
      readyState: this.ws ? this.ws.readyState : 'null',
      readyStateText: this.ws ? ['CONNECTING', 'OPEN', 'CLOSING', 'CLOSED'][this.ws.readyState] : 'NO_CONNECTION',
      messageListeners: this.messageListeners.length,
      reconnectAttempts: this.reconnectAttempts,
      isManualClose: this.isManualClose
    }
    console.table(info)
    return info
  }
}

// 创建全局 WebSocket 管理器实例
export const wsManager = new WebSocketManager()

// 暴露到全局作用域，方便浏览器控制台调试
if (typeof window !== 'undefined') {
  window.__wsManager = wsManager
  window.__checkWebSocket = () => wsManager.getDebugInfo()
  console.log('💡 提示：在控制台输入 window.__checkWebSocket() 可查看 WebSocket 状态')
}

export default WebSocketManager
